from django.shortcuts import render

# Create your views here.
from rest_framework.response import Response

from orders.models import OrderInfo


# Create your views here.
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework import status
from mall import settings
from alipay import AliPay

from pay.models import Payment

"""
1. 创建应用(使用沙箱应用) app_id,网关(相当于 api.meiduo.site)
2. 设置2对 公钥和私钥
    1对是 我们的应用的
        公钥      需要保存到支付宝网站上
        私钥      需要保存在我们的工程一个目录中
    1对是支付宝的
        私钥      在支付宝的服务器上,它自己生成的
        公钥      我们需要在支付宝的网站上把他复制下来,放在一个 有 公钥开始和结束标志的文件中
3. 设置环境(appid,公钥私钥,sdk)

4. 按照文档开发

"""


"""

 当用户点击支付按钮的时候,我们需要让前端发送一个ajax请求,将 订单id发送给我们
必须是登录用户才可以访问此接口

 1. 我们接收参数, 校验参数
 2. 根据订单id查询数据
 3. 创建支付宝对象
 4. 调用支付宝的方法生成order_string
 5. 拼接url,并且返回

 GET    /pay/(?P<order_id>\d+)/payment/


"""
class PaymentView(APIView):

    permission_classes = [IsAuthenticated]

    def get(self,request,order_id):
        # 1. 我们接收参数, 校验参数
        # 2. 根据订单id查询数据
        try:
            # 为了让我们查询的更准确,我们需要再添加几个查询条件
            # 查询未支付的订单
            # 查询这个用户的订单
            order = OrderInfo.objects.get(order_id=order_id,
                                          user=request.user,
                                          status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
        except OrderInfo.DoesNotExist:
            return Response(status.HTTP_400_BAD_REQUEST)
        # 3. 创建支付宝对象

        app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read()
        alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read()

        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            app_private_key_string=app_private_key_string,
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            alipay_public_key_string=alipay_public_key_string,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug = settings.ALIPAY_DEBUG  # 默认False
        )


        # 4. 调用支付宝的方法生成order_string
        # 如果你是 Python 3的用户，使用默认的字符串即可
        subject = "测试订单"

        # 电脑网站支付，需要跳转到https://openapi.alipay.com/gateway.do? + order_string
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,
            total_amount=str(order.total_amount), # 这里类型我们要由 decimal转换为 str
            subject=subject,
            return_url="http://www.meiduo.site:8080/pay_success.html",
            notify_url=None  # 可选, 不填则使用默认notify url
        )

        # 5. 拼接url,并且返回
        url = settings.ALIPAY_URL + '?' + order_string

        return Response({'alipay_url':url})

"""
我们通过 git文档中的验证就可以实现 支付结果的查询

我们需要使用 支付宝回传过来的一些字符串
这些字符串需要让前端传递过来

    put  pay/status/?xxxx&xxxxx&xxxx

"""

class PayStatusAPIView(APIView):
    def put(self,request):
        # 1.创建支付宝对象
        app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read()
        alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read()

        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            app_private_key_string=app_private_key_string,
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            alipay_public_key_string=alipay_public_key_string,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG  # 默认False
        )
        # 2.验证
        data = request.query_params.dict()
        # sign 不能参与签名验证
        signature = data.pop("sign")
        # verify
        success = alipay.verify(data, signature)
        if success:
            # 验证成功后,可以从date中获取 支付宝的订单id 和 我们的订单id
            # 支付宝的订单id
            trade_id = data.get('trade_no')
            # 商家订单id
            out_trade_no =data.get('out_trade_no')
            # 1.把支付宝的订单id和我们的订单id保存起来
            Payment.objects.create(
                trade_id=trade_id,
                order_id=out_trade_no
            )
            # 2.更新订单的状态
            OrderInfo.objects.filter(order_id=out_trade_no).update(status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'])
            # 3.返回支付宝的订单id
            return Response({'trade_id':trade_id})